/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.    
*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Data;

namespace DBConnection
{
    /// <summary>
    /// DataBase Type MSSQL, ODBC or OLE
    /// </summary>
    public enum DataBaseType
    {
        /// <summary>
        /// Microsoft SQL
        /// </summary>
        MSSQL,
        /// <summary>
        /// ODBC Source
        /// </summary>
        ODBC,
        /// <summary>
        /// OLE Source
        /// </summary>
        OLE
    }

    /// <summary>
    /// Wrapper around the DBConnection, BindingSource and DataSet
    /// </summary>
    public class CDataSource
    {
        /// <summary>
        /// Database Type MSSQL,ODBC or OLE
        /// </summary>
        private DataBaseType m_DataBaseType;
        /// <summary>
        /// Database Connection Pointer
        /// </summary>
        private IDBSourceConnection mp_DBConnection;
        /// <summary>
        /// DataSet associated with DataSource
        /// </summary>
        private DataSet m_DataSourceDataSet;
        /// <summary>
        /// List of Tables assoicated with their bindingsources
        /// </summary>
        private Dictionary<string, BindingSource> TableBindings = new Dictionary<string, BindingSource>();

        /// <summary>
        /// Property to get DataSet
        /// </summary>
        public DataSet DataSourceDataSet
        {
            get
            {
                return (m_DataSourceDataSet);
            }
            set
            {
                m_DataSourceDataSet = value;
            }
        }

        /// <summary>
        /// Property to get the connection. Do not forget to cast back to what you need
        /// </summary>
        public IDBSourceConnection DataBaseConnection
        {
            get
            {
                return (mp_DBConnection);
            }
            set
            {
                try
                {
                    throw(new Exception("Can not set the Database connection recreate the datasource to do this"));
                }
                catch(Exception ex)
                {
                    CMsgBox.ShowMsgBox(ex.Message);
                }
            }
        }

        /// <summary>
        /// Default Constructor do not use
        /// </summary>
        public CDataSource()
        {
        }

        /// <summary>
        /// Main Constructor please use this constructor
        /// </summary>
        /// <param name="DBTypeIn">Pass in the Database Type MSSQL, ODBC or OLE</param>
        /// <param name="strConnString">Connection String</param>
        /// <param name="strFormName">The Name of the Form the DataSource is associated with</param>
        public CDataSource(DataBaseType DBTypeIn, string strConnString, string strFormName)
        {
            try
            {
                m_DataBaseType = DBTypeIn;

                switch (m_DataBaseType)
                {
                    case DataBaseType.MSSQL:
                        SQLDBConnection SQLDB = new SQLDBConnection(strConnString);
                        mp_DBConnection = SQLDB;
                        break;
                    case DataBaseType.ODBC:
                        ODBCConnection ODBCDB = new ODBCConnection(strConnString);
                        mp_DBConnection = ODBCDB;
                        break;
                    case DataBaseType.OLE:
                        OLEConnection OLEDB = new OLEConnection(strConnString);
                        mp_DBConnection = OLEDB;
                        break;
                }

                m_DataSourceDataSet = DataHandling.RequestNewDataSet(strFormName);
            }
            catch (Exception ex)
            {
                CMsgBox.ShowMsgBox(ex.Message);
            }
        }

        /// <summary>
        /// Refresh an Existing DataTable
        /// </summary>
        /// <param name="strTableName">AdapterName</param>
        public void RefreshTable(string strTableName)
        {            
            try
            {
                mp_DBConnection.Connect();
                    BindingSource BS = TableBindings[strTableName];
                    mp_DBConnection.RefreshExistingDataTable((DataTable)BS.DataSource, strTableName);                  
                mp_DBConnection.Disconnect();

            }
            catch (Exception ex)
            {
                CMsgBox.ShowMsgBox(ex.Message);
            }

        }


        /// <summary>
        /// Add A new Table to the DataSource
        /// </summary>
        /// <param name="strActualTableName">Acutal Table Name you are wanting to use an update, delete or insert on</param>
        /// <param name="strTableName">Name of Table</param>
        /// <param name="strSql">Sql in Table</param>
        /// <param name="bAutoGenInsertUpdate">Do you want to request an auto gen of the insert, update etc</param>
        /// <param name="bMSSQLAutoGen">Do you want the MSSQL Alternative AutoGenCommandBuilder?. Always set false for ODBC or OLE </param>
        public void AddTable(string strActualTableName, string strTableName, string strSql, bool bAutoGenInsertUpdate, bool bMSSQLAutoGen)
        {
            DataTable DT;
            try
            {
                mp_DBConnection.Connect();
                DT = mp_DBConnection.RequestDataTableUsingSQLAdapter(strSql, strTableName);
                BindingSource BS = new BindingSource();
                BS.DataSource = DT;                
                TableBindings.Add(strTableName, BS);
                m_DataSourceDataSet.Tables.Add(DT);

                if (bAutoGenInsertUpdate)
                {
                    if (bMSSQLAutoGen)
                    {
                        SQLDBConnection SQLDB = (SQLDBConnection)mp_DBConnection;
                        SQLDB.AutoGenUpdateDeleteInsertAlternativeForMSSQL(strTableName,ref DT, strActualTableName);
                    }
                    else
                    {
                        mp_DBConnection.AutoGenUpdateDeleteInsert(strTableName);
                    }
                }
              
                mp_DBConnection.Disconnect();
            }
            catch (Exception ex)
            {
                CMsgBox.ShowMsgBox(ex.Message);
            }
        }

        /// <summary>
        /// Get the BindingSource associated to the Table
        /// </summary>
        /// <param name="strTableName">Table Name</param>
        /// <returns>BindingSource for that Table</returns>
        public BindingSource GetBindingSourceForTable(string strTableName)
        {
            return (TableBindings[strTableName]);
        }

        /// <summary>
        /// Remove a Table from the DataSource
        /// </summary>
        /// <param name="strTableName">Table Name</param>
        public void RemoveTable(string strTableName)
        {
            try
            {
                TableBindings.Remove(strTableName);
                m_DataSourceDataSet.Tables.Remove(strTableName);
                mp_DBConnection.ClearTableAdapter(strTableName);
            }
            catch (Exception)
            {                
                //CMsgBox.ShowMsgBox(ex.Message);
            }
        }

        /// <summary>
        /// Update a Table in the Database in the Data Source
        /// </summary>
        /// <param name="strTableName">Table Name</param>
        public void UpdateTable(string strTableName)
        {
            try
            {
               // mp_DBConnection.Connect();
                mp_DBConnection.UpdateDataInAdapter(strTableName, m_DataSourceDataSet,strTableName);
               // mp_DBConnection.Disconnect();
            }
            catch (Exception ex)
            {
               // CMsgBox.ShowMsgBox(ex.Message);
                throw new Exception(ex.Message);
            }
        }

    }
}
